<?php
/**
 * This file is part of Hyperf Mall.
 *
 * @link     https://gitee.com/scwlkj/hyperf_mall
 * contact  hyperf_mall@163.com
 */
declare(strict_types=1);

namespace App\Command;

use Hyperf\Command\Command as HyperfCommand;
use Hyperf\Command\Annotation\Command;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\StreamOutput;

/**
 * @Command
 */
#[Command]
class LazyServiceCommand extends HyperfCommand
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var string
     */
    protected $pre;

    /**
     * @var array
     */
    protected $names;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;

        parent::__construct('lazy:service');
    }

    public function configure()
    {
        parent::configure();
        $this->addArgument('name',InputArgument::OPTIONAL,'表名','member_point');
        $this->addArgument('service',InputArgument::OPTIONAL,'服务名','member');
        $this->setDescription('懒人一键生成代码命令');
    }

    public function handle()
    {
        $this->line('代码生成中...', 'info');
        $name =  $this->input->getArgument('name');
        $service =  $this->input->getArgument('service');
        $this->makeName($name,$service);

        //$this->makeController();
        $this->makeService();
        $this->makeInterface();
        $this->makeConfigServices();

    }

    private function makeName($name,$service = '')
    {
        $pre = ucfirst(preg_replace_callback('/_([A-Za-z])/',function ($matches){
            return strtoupper($matches[1]);
        },$name));

        $this->names = [
            'service' => ucfirst($service),
            'service_name'=> $pre . 'Service',
            'service_path' => BASE_PATH . '/app/Service/' . ($service ? (ucfirst($service) . '/') : '') . $pre .'Service.php',
            'interface_name' => $pre .'ServiceInterfaces',
            'interface_path' => BASE_PATH . '/app/Service/' . ($service ? (ucfirst($service) . '/') : '') . 'Interfaces/' . $pre .'ServiceInterfaces.php',
            'controller_name' => $pre . 'Controller',
            'controller_path' => BASE_PATH . '/app/Controller/' . ($service ? (ucfirst($service) . '/') : '') . $pre .'Controller.php',
            'config_service_path' => BASE_PATH . '/config/services/' . ($service ? (($service) . '/') : '') . $pre .'Service.php',
            'host' => strtoupper($service) . '_RPC_HOST',
            'port' => strtoupper($service) . '_RPC_PORT'
        ];
    }

    private function makeController(){
        $this->makeDir($this->names['controller_path'],$this->names['controller_name']);
        $output = new StreamOutput(fopen($this->names['controller_path'], 'w+', false));
        $output->writeln("<?php");
        $output->writeln("/**");
        $output->writeln(" * This file is part of Hyperf Mall.");
        $output->writeln(" * ");
        $output->writeln(" * @link     https://gitee.com/scwlkj/hypref_mall");
        $output->writeln(" * contact  hyperf_mall@163.com");
        $output->writeln(" */");
        $output->writeln("");
        $output->writeln("declare(strict_types=1);");
        $output->writeln("");
        $output->writeln("namespace App\\Controller\\{$this->names['service']};");
        $output->writeln("");

        $output->writeln("use App\\Controller\\BaseController;");
        $output->writeln("use App\\Service\\{$this->names['service']}\\{$this->names['service_name']};");
        $output->writeln("use Hyperf\HttpServer\Annotation\Controller;");

        $output->writeln("");

        $output->writeln("/**");
        $output->writeln(" * @Controller()");
        $output->writeln(" */");

        $output->writeln("class {$this->names['controller_name']} extends BaseController ");
        $output->writeln("{");
        $output->writeln("    public function __construct()");
        $output->writeln("    {");
        $output->writeln("        \$this->service = ".$this->names['service_name']."::getInstance();");
        $output->writeln("    }");
        $output->writeln("}");

        $this->line($this->names['controller_path'] . "创建成功！", 'info');
    }

    private function makeService()
    {
        $this->makeDir($this->names['service_path'],$this->names['service_name']);
        $output = new StreamOutput(fopen($this->names['service_path'], 'w+', false));
        $output->writeln("<?php");
        $output->writeln("/**");
        $output->writeln(" * This file is part of Hyperf Mall.");
        $output->writeln(" * ");
        $output->writeln(" * @link     https://gitee.com/scwlkj/hypref_mall");
        $output->writeln(" * contact  hyperf_mall@163.com");
        $output->writeln(" */");
        $output->writeln("");
        $output->writeln("declare(strict_types=1);");
        $output->writeln("");
        $output->writeln("namespace App\\Service\\{$this->names['service']};");
        $output->writeln("");
        $output->writeln("use App\\Service\\BaseService;");
        $output->writeln("use App\\Service\\{$this->names['service']}\\Interfaces\\{$this->names['interface_name']};");
        $output->writeln("use Hyperf\\RpcServer\\Annotation\\RpcService;");
        $output->writeln("use Hyperf\\Di\\Annotation\\Inject;");
        $output->writeln("");

        $output->writeln("/**");
        $output->writeln(" * Class {$this->names['service_name']}");
        $output->writeln(" * @package  App\\Service\\{$this->names['service']}");
        $output->writeln(" * @method index(array \$condition, array \$field, int \$page, int \$size)");
        $output->writeln(" * @method update(int \$id, array \$data)");
        $output->writeln(" * @method delete(int \$id)");
        $output->writeln(" * @method add(array \$data)");
        $output->writeln(" * @method getRows(array \$condition, array \$field)");
        $output->writeln(" * @method getOne(array \$condition, array \$field = ['*'])");
        $output->writeln(" */");

        $output->writeln("class ".$this->names['service_name']." extends BaseService");
        $output->writeln("{");

        $output->writeln("     /**");
        $output->writeln("      * @Inject()");
        $output->writeln("      * @var {$this->names['interface_name']}");
        $output->writeln("      */");
        $output->writeln("      protected \$service;");
        $output->writeln("}");

        $this->line($this->names['service_path'] . "创建成功！", 'info');
    }

    private function makeInterface()
    {
        $this->makeDir($this->names['interface_path'],$this->names['interface_name']);
        $output = new StreamOutput(fopen($this->names['interface_path'], 'w+', false));
        $output->writeln("<?php");
        $output->writeln("/**");
        $output->writeln(" * This file is part of Hyperf Mall.");
        $output->writeln(" * ");
        $output->writeln(" * @link     https://gitee.com/scwlkj/hypref_mall");
        $output->writeln(" * contact  hyperf_mall@163.com");
        $output->writeln(" */");
        $output->writeln("");
        $output->writeln("declare(strict_types=1);");
        $output->writeln("");
        $output->writeln("namespace App\\Service\\{$this->names['service']}\\Interfaces;");
        $output->writeln("");
        $output->writeln("interface ".$this->names['interface_name']);
        $output->writeln("{");
        $output->writeln("  public function initFunction(array \$args): array;");
        $output->writeln("}");

        $this->line($this->names['interface_path'] . "创建成功！", 'info');
    }

    private function makeConfigServices()
    {
        $this->makeDir($this->names['config_service_path'],$this->names['service_name']);
        $output = new StreamOutput(fopen($this->names['config_service_path'], 'w+', false));
        $output->writeln("<?php");
        $output->writeln("/**");
        $output->writeln(" * This file is part of Hyperf Mall.");
        $output->writeln(" * ");
        $output->writeln(" * @link     https://gitee.com/scwlkj/hypref_mall");
        $output->writeln(" * contact  hyperf_mall@163.com");
        $output->writeln(" */");
        $output->writeln("");
        $output->writeln("declare(strict_types=1);");
        $output->writeln("");
        $output->writeln("return [");
        $output->writeln("    'name' => '{$this->names['service']}::{$this->names['service_name']}',");
        $output->writeln("    'service' => \\App\\Service\\{$this->names['service']}\\Interfaces\\{$this->names['interface_name']}::class,");
        $output->writeln("    'nodes' => [");
        $output->writeln("        ['host' => env('{$this->names['host']}', '127.0.0.1'), 'port' => (int)env('{$this->names['port']}')],");
        $output->writeln("    ],");
        $output->writeln("];");

        $this->line($this->names['config_service_path'] . "创建成功！", 'info');
    }

    private function makeDir($path,$name)
    {
        $path = trim($path,($name . '.php'));
        if (!is_dir($path)){
            mkdir($path);
        }
    }
}
